#include "blog.hh"

const unsigned int Blog::blockSize=512;

 // {{{  Blog::RootNode::read
void Blog::RootNode::read(str data)
{
	uint32_t n;
	const char *p=data.cstr();

	// Read the length of title
	memcpy(&n,p,sizeof(n));
	n=ntohl(n);
	p+=sizeof(n);
	
	// Read the title
	m_title=str(p,n);
	p+=n;

	// Read the amount of articles
	memcpy(&n,p,sizeof(n));
	n=ntohl(n);
	p+=sizeof(n);
//	warn << "n=" << n << "\n";
//	warn << "sha1::hashsize=" << (int)(sha1::hashsize) << "\n";

	// Read articles
	for (unsigned int i=0; i<n; ++i) {
		bigint id;
		mpz_set_rawmag_be (&id, p, sha1::hashsize);
		p+=sha1::hashsize;
		m_articles.push_back(id);
	}

	warn << "Title: >" << m_title << "<\n";
	warn << "Articles: " << n << "\n";
	for (std::vector<bigint>::const_iterator i=m_articles.begin(); i!=m_articles.end(); ++i)
		warn << "\t" << *i << "\n";
};
// }}} 
// {{{  Blog::RootNode::write
str Blog::RootNode::write()
{
        warn << "Blog::RootNode::write() " << "\n";

	strbuf buf;
	uint32_t n=htonl(m_title.len());
	buf << str((char *)&n,sizeof(n));
	buf << m_title;
	n=htonl(m_articles.size());
	buf << str((char *)&n,sizeof(n));
	for (std::vector<bigint>::const_iterator i=m_articles.begin(); i!=m_articles.end(); ++i) {
		char b[sha1::hashsize];
		mpz_get_raw (b, sha1::hashsize, &(*i));
		buf << str(b,sha1::hashsize);
	}
	str tmp=buf;
	
//	for (unsigned int i=Blog::blockSize-tmp.len(); i>0; --i)
//		buf << (char)0;
//	tmp=buf;
	
	if (tmp.len()>Blog::blockSize)
		n=0;//FIXME
	return tmp;
}
// }}}

bigint Blog::createNewBlog(ptr<IncognitoBlockingClient> ibc)
{
	warn << "Blog::createNewBlog(): start.... " << "\n";
	bigint id=make_randomID();
	Blog::RootNode node;
	str s=node.write();

	warn << "Blog::createNewBlog(): invoking insert.... \n";
	id=ibc->insert(id,s,false);

	return id;
}

Blog::Blog(ptr<IncognitoBlockingClient> ibc, bigint rootid):m_rootID(rootid),m_ibc(ibc)
{
	str s=m_ibc->retrieve(m_rootID,false);
//	warn << "Blog::Blog() s= >" << s << "< " << s.len() << "\n";
	m_root.read(s);
}

void Blog::saveRoot() 
{
	str s=m_root.write();
	warn << "Blog::saveRoot() s= >" << s << "< " << s.len() << "\n";
	warn << "Blog::saveRoot() id= " << m_rootID << "\n";
	m_ibc->insert(m_rootID,s,false);
}

// {{{ Blog::addArticle
bigint Blog::addArticle(str title, str content)
{
	strbuf buf;
	uint32_t n=htonl(title.len());
	buf << str((char *)&n,sizeof(n));
	buf << title;
	n=htonl(content.len());
	buf << str((char *)&n,sizeof(n));
	buf << content;
	str tmp=buf;

	if (tmp.len()>Blog::blockSize)
		n=0;//FIXME
	
	bigint artid=m_ibc->insert(tmp);
	//m_articles.push_back(artid);
	m_root.addArticle(artid);

	return artid;
}
 // }}} 

 // {{{ Blog::getArticle
void Blog::getArticle(bigint artid, str &title, str &content)
{
	str data=m_ibc->retrieve(artid,true);
	uint32_t n;
	const char *p=data.cstr();

	// Read the title length
	memcpy(&n,p,sizeof(n));
	n=ntohl(n);
	p+=sizeof(n);
	
	// Read the title
	title=str(p,n);
	p+=n;

	// Read the content length
	memcpy(&n,p,sizeof(n));
	n=ntohl(n);
	p+=sizeof(n);
	
	// Read the content
	content=str(p,n);
}
// }}} 






// vim: foldmethod=marker

